home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Languages / MacQForth 1.0 / asm6502 / documentation / Assembly in One Step < prev   
Text File  |  1995-03-20  |  33KB  |  331 lines

  1.  
  2. Assembly in one step
  3. --------------------
  4.  
  5.  
  6. A brief guide to programming the 6502 in assembly language.  It will 
  7. introduce the 6502 architecture, addressing modes, and instruction set.
  8. No prior assembly language programming is assumed, however it is assumed 
  9. that you are somewhat familiar with hexadecimal numbers.  Programming
  10. examples are given at the end.  After reading this it is recommended that 
  11. you review the file 6502 INSTRUCTION SUMMARY.  Much of this material 
  12. comes from _6502 Software Design_ by Leo Scanlon, Blacksburg, 1980.
  13.  
  14.  
  15. ================================================================================
  16.  
  17.  
  18. The 6502 Architecture
  19. ---------------------
  20.  
  21.    The 6502 is an 8-bit microprocessor that follows the memory oriented 
  22.    design philosophy of the Motorola 6800.  Several engineers left 
  23.    Motorola and formed MOS Technology which introduced the 6502 in 1975.  
  24.    The 6502 gained in popularity because of it's low price and became the 
  25.    heart of several early personal computers including the Apple II, 
  26.    Commodore 64, and Atari 400 and 800.
  27.    
  28.    
  29.    Simplicity is key
  30.    -----------------
  31.    
  32.    The 6502 handles data in its registers, each of which holds one byte 
  33.    (8-bits) of data.  There are a total of three general use and two special
  34.    purpose registers:
  35.    
  36.    
  37.       accumulator (A)  -  Handles all arithmetic and logic.  The real heart
  38.                           of the system.
  39.                           
  40.       X and Y          -  General purpose registers with limited abilities.
  41.       
  42.       S                -  Stack pointer.
  43.       
  44.       P                -  Processor status.  Holds the result of tests 
  45.                           and flags.
  46.                           
  47.                           
  48.    All of the 6502 is implemented in MacQForth with the exception of 
  49.    interrupts and decimal mode arithmetic.
  50.    
  51.    
  52.    Stack Pointer
  53.    -------------
  54.    
  55.    When the microprocessor executes a JSR (Jump to SubRoutine) 
  56.    instruction it needs to know where to return when finished.  The 6502 
  57.    keeps this information in low memory from $0100 to $01FF and uses the 
  58.    stack pointer as an offset.  The stack grows down from $01FF and makes 
  59.    it possible to nest subroutines up to 128 levels deep.  Not a problem 
  60.    in most cases.
  61.    
  62.    
  63.    Processor Status
  64.    ----------------
  65.    
  66.    The processor status register is not directly accessible by any 6502 
  67.    instruction.  Instead, there exist numerous instructions that test the 
  68.    bits of the processor status register.  The flags within the register 
  69.    are:
  70.    
  71.    
  72.        bit ->   7                           0
  73.               +---+---+---+---+---+---+---+---+
  74.               | N | V |   | B | D | I | Z | C |  <-- flag, 0/1 = reset/set
  75.               +---+---+---+---+---+---+---+---+
  76.               
  77.               
  78.        N  =  NEGATIVE. Set if bit 7 of the accumulator is set.
  79.        
  80.        V  =  OVERFLOW. Set if the addition of two like-signed numbers or the
  81.              subtraction of two unlike-signed numbers produces a result
  82.              greater than +127 or less than -128.
  83.              
  84.        B  =  BRK COMMAND. Set if an interrupt caused by a BRK, reset if
  85.              caused by an external interrupt.  Not used in MacQForth.
  86.              
  87.        D  =  DECIMAL MODE. Set if decimal mode active.  Not used in MacQForth.
  88.        
  89.        I  =  IRQ DISABLE.  Set if maskable interrupts are disabled.  Not
  90.              used in MacQForth.
  91.              
  92.        Z  =  ZERO.  Set if the result of the last operation (load/inc/dec/
  93.              add/sub) was zero.
  94.              
  95.        C  =  CARRY. Set if the add produced a carry, or if the subtraction
  96.              produced a borrow.  Also holds bits after a logical shift.
  97.              
  98.              
  99.    Accumulator
  100.    -----------
  101.    
  102.    The majority of the 6502's business makes use of the accumulator.  All 
  103.    addition and subtraction is done in the accumulator.  It also handles 
  104.    the majority of the logical comparisons (is A > B ?) and logical bit 
  105.    shifts.
  106.    
  107.    
  108.    X and Y
  109.    -------
  110.    
  111.    These are index registers often used to hold offsets to memory 
  112.    locations.  They can also be used for holding needed values.  Much of 
  113.    their use lies in supporting some of the addressing modes.
  114.    
  115.  
  116.    
  117. Addressing Modes
  118. ----------------
  119.  
  120.    The 6502 has 13 addressing modes, or ways of accessing memory.  The 65C02 
  121.    introduces two additional modes.
  122.    
  123.    They are:
  124.    
  125.    
  126.       +---------------------+--------------------------+
  127.       |      mode           |     assembler format     |
  128.       +=====================+==========================+
  129.       | Immediate           |          #aa             |
  130.       | Absolute            |          aaaa            |
  131.       | Zero Page           |          aa              |   Note:
  132.       | Implied             |                          |
  133.       | Indirect Absolute   |          (aaaa)          |     aa = 2 hex digits
  134.       | Absolute Indexed,X  |          aaaa,X          |          as $FF
  135.       | Absolute Indexed,Y  |          aaaa,Y          |
  136.       | Zero Page Indexed,X |          aa,X            |     aaaa = 4 hex
  137.       | Zero Page Indexed,Y |          aa,Y            |          digits as
  138.       | Indexed Indirect    |          (aa,X)          |          $FFFF
  139.       | Indirect Indexed    |          (aa),Y          |
  140.       | Relative            |          aaaa            |     Can also be
  141.       | Accumulator         |          A               |     assembler labels
  142.       +---------------------+--------------------------+
  143.       
  144.       (Table 2-3. _6502 Software Design_, Scanlon, 1980)
  145.       
  146.    
  147.    Immediate Addressing
  148.    --------------------
  149.    
  150.    The value given is a number to be used immediately by the 
  151.    instruction.  For example, LDA #$99 loads the value $99 into the 
  152.    accumulator.
  153.    
  154.    
  155.    Absolute Addressing
  156.    -------------------
  157.    
  158.    The value given is the address (16-bits) of a memory location that 
  159.    contains the 8-bit value to be used.  For example, STA $3E32 stores 
  160.    the present value of the accumulator in memory location $3E32.
  161.    
  162.    
  163.    Zero Page Addressing
  164.    --------------p
  165.     -----------------
  166.     
  167.             ; 
  168.             ; An 8-bit count down loop
  169.             ;
  170.             
  171.             start LDX #$FF    ; load X with $FF = 255
  172.             loop  DEX         ; X = X - 1
  173.                   BNE loop    ; if X not zero then goto loop
  174.                   RTS         ; return
  175.                   
  176.             How does the BNE instruction know that X is zero?  It 
  177.             doesn't, all it knows is that the Z flag is set or reset.  
  178.             The DEX instruction will set the Z flag when X is zero.
  179.                   
  180.                   
  181.             ;
  182.             ; A 16-bit count down loop
  183.             ;
  184.             
  185.             start LDY #$FF    ; load Y with $FF
  186.             loop1 LDX #$FF    ; load X with $FF
  187.             loop2 DEX         ; X = X - 1
  188.                   BNE loop2   ; if X not zero goto loop2
  189.                   DEY         ; Y = Y - 1
  190.                   BNE loop1   ; if Y not zero goto loop1
  191.                   RTS         ; return
  192.                   
  193.             There are two loops here, X will be set to 255 and count to 
  194.             zero for each time Y is decremented.  The net result is to 
  195.             count the 16-bit number Y (high) and X (low) down from $FFFF 
  196.             = 65535 to zero.
  197.             
  198.             
  199.     Other examples
  200.     --------------
  201.     
  202.     ** Note: All of the following examples are lifted nearly verbatim from 
  203.              the book "6502 Software Design", whose reference is above. 
  204.              
  205.              
  206.            ; Example 4-2.  Deleting an entry from an unordered list
  207.            ;
  208.            ; Delete the contents of $2F from a list whose starting
  209.            ; address is in $30 and $31.  The first byte of the list
  210.            ; is its length.
  211.            ;
  212.            
  213.            deluel  LDY #$00      ; fetch element count
  214.                    LDA ($30),Y
  215.                    TAX          ; transfer length to X
  216.                    LDA $2F      ; item to delete
  217.            nextel  INY          ; index to next element
  218.                    CMP ($30),Y  ; do entry and element match?
  219.                    BEQ delete   ; yes. delete element
  220.                    DEX          ; no. decrement element count
  221.                    BNE nextel   ; any more elements to compare?
  222.                    RTS          ; no. element not in list. done
  223.                    
  224.            ; delete an element by moving the ones below it up one location
  225.            
  226.            delete  DEX          ; decrement element count
  227.                    BEQ deccnt   ; end of list?
  228.                    INY          ; no. move next element up
  229.                    LDA ($30),Y
  230.                    DEY
  231.                    STA ($30),Y
  232.                    INY
  233.                    JMP delete
  234.            deccnt  LDA ($30,X)  ; update element count of list
  235.                    SBC #$01
  236.                    STA ($30,X)
  237.                    RTS
  238.                    
  239.                    
  240.                    
  241.            
  242.            ; Example 5-6.  16-bit by 16-bit unsigned multiply
  243.            ;
  244.            ; Multiply $22 (low) and $23 (high) by $20 (low) and
  245.            ; $21 (high) producing a 32-bit result in $24 (low) to $27 (high)
  246.            ;
  247.            
  248.            mlt16   LDA #$00     ; clear p2 and p3 of product
  249.                    STA $26
  250.                    STA $27
  251.                    LDX #$16     ; multiplier bit count = 16
  252.            nxtbt   LSR $21      ; shift two-byte multiplier right
  253.                    ROR $20
  254.                    BCC align    ; multiplier = 1?
  255.                    LDA $26      ; yes. fetch p2
  256.                    CLC
  257.                    ADC $22      ; and add m0 to it
  258.                    STA $26      ; store new p2
  259.                    LDA $27      ; fetch p3
  260.                    ADC $23      ; and add m1 to it
  261.            align   ROR A        ; rotate four-byte product right
  262.                    STA $27      ; store new p3
  263.                    ROR $26
  264.                    ROR $25
  265.                    ROR $24
  266.                    DEX          ; decrement bit count
  267.                    BNE nxtbt    ; loop until 16 bits are done
  268.                    RTS
  269.                    
  270.                    
  271.                    
  272.            ; Example 5-14.  Simple 16-bit square root.
  273.            ;
  274.            ; Returns the 8-bit square root in $20 of the
  275.            ; 16-bit number in $20 (low) and $21 (high). The
  276.            ; remainder is in location $21.
  277.            
  278.            sqrt16  LDY #$01     ; lsby of first odd number = 1
  279.                    STY $22
  280.                    DEY
  281.                    STY $23      ; msby of first odd number (sqrt = 0)
  282.            again   SEC
  283.                    LDA $20      ; save remainder in X register
  284.                    TAX          ; subtract odd lo from integer lo
  285.                    SBC $22
  286.                    STA $20
  287.                    LDA $21      ; subtract odd hi from integer hi
  288.                    SBC $23
  289.                    STA $21      ; is subtract result negative?
  290.                    BCC nomore   ; no. increment square root
  291.                    INY
  292.                    LDA $22      ; calculate next odd number
  293.                    ADC #$01
  294.                    STA $22
  295.                    BCC again
  296.                    INC $23
  297.                    JMP again
  298.             nomore STY $20      ; all done, store square root
  299.                    STX $21      ; and remainder
  300.                    RTS
  301.          
  302.            
  303.            This is based on the observation that the square root of an 
  304.            integer is equal to the number of times an increasing odd 
  305.            number can be subtracted from the original number and remain 
  306.            positive.  For example,
  307.            
  308.                    25
  309.                  -  1         1
  310.                    --
  311.                    24
  312.                  -  3         2
  313.                    --
  314.                    21
  315.                  -  5         3
  316.                    --
  317.                    16
  318.                  -  7         4
  319.                    --
  320.                     9
  321.                  -  9         5 = square root of 25
  322.                    --
  323.                     0
  324.  
  325.  
  326. If you are truly interested in learning more, go to your public library 
  327. and seek out an Apple machine language programming book.  If your public 
  328. library is like mine, there will still be plenty of early 80s computer 
  329. books on the shelves. :)
  330.  
  331.